<?php


namespace app\index\controller;

class Buy extends \app\common\Controller
{
	public function code()
	{
		$id = "BuyPublic";
		$config = ["fontSize" => 50, "length" => 4, "useNoise" => true, "reset" => true, "useCurve" => false];
		$captcha = new \think\captcha\Captcha($config);
		return $captcha->entry($id);
	}
	public function CardBuyView($appid)
	{
		$app = \think\Db::name("app")->where(["id" => $appid])->find();
		if (empty($app)) {
			return json(["code" => -1, "msg" => "应用ID不存在"]);
		}
		$this->assign("appid", $appid);
		$this->assign("app", $app);
		$this->assign("input", input());
		$this->assign("pay_config", \app\common\server\ConfigServer::get("pay", "config"));
		$this->assign("buy_config", json_decode($app["buy_config"], true));
		$CardTimeType = \app\common\model\CardTimeType::ClearCache();
		if ($app["type"] == 1) {
			$CardTimeType = array_map(function ($item) {
				return [$item[0], $item[1] . "-会员"];
			}, $CardTimeType);
			$CardTimeType[] = ["point", "积分"];
			$CardTimeType[] = ["register_code", "注册码"];
		}
		if ($app["type"] == 2) {
			$CardTimeType[] = ["point", "积分"];
		}
		$this->assign("CardTimeType", $CardTimeType);
		if (isset($this->input["id"]) && isset($this->input["key"])) {
			$order = \think\Db::name("app_order")->where(["id" => $this->input["id"], "appid" => $appid])->find();
			if (!empty($order) && $this->input["key"] == \app\common\service\AppCardBuy::getOrderKey($order)) {
				$orderInfo = \app\common\service\AppCardBuy::getCardBuyOrderArray($order, false);
			}
		}
		$this->assign("orderInfo", $orderInfo ?? []);
		$this->assign("appInfo", ["id" => $app["id"], "name" => $app["name"], "avatar" => $app["avatar"], "type" => $app["type"]]);
		return $this->fetch("./view/CardAppBuy.html");
	}
	public function CreateCardBuyOrder() : \think\response\Json
	{
		$post = $this->request->post();
		$validate = \think\Validate::make(["appid" => "require", "pay_type" => "require|in:1,2,3", "type" => "require", "value" => "require|number|>=:1", "phone" => "require|mobile", "num" => "require|number|>=:1", "code" => "require"], ["appid.require" => "appid 不能为空", "pay_type.require" => "请选择支付方式", "type.require" => "卡密类型 不能为空", "value.require" => "卡密面值 不能为空", "num.require" => "购买数量 不能为空", "phone.require" => "手机号码 不能为空", "phone.mobile" => "手机号码 格式不正确", "code.require" => "验证码 格式不正确"]);
		if (!$validate->check($post)) {
			return json(["code" => -1, "msg" => $validate->getError()]);
		}
		if (!captcha_check($post["code"], "BuyPublic")) {
			return json(["code" => -1, "msg" => "验证码错误"]);
		}
		$result = \app\common\service\AppCardBuy::createCardBuyOrder($post);
		if ($result["code"] != 1) {
			return json($result);
		}
		return json(["code" => 1, "msg" => "创建订单成功", "data" => $result["data"]]);
	}
	public function CreateRenewalOrder() : \think\response\Json
	{
		$post = $this->request->post();
		$validate = \think\Validate::make(["appid" => "require", "pay_type" => "require|in:1,2,3", "type" => "require", "value" => "require|number|>=:1", "user" => "require", "code" => "require"], ["appid.require" => "appid 不能为空", "pay_type.require" => "请选择支付方式", "type.require" => "时长类型 不能为空", "value.require" => "时长面值 不能为空", "user.require" => "用户信息 不能为空", "code.require" => "验证码 格式不正确"]);
		if (!$validate->check($post)) {
			return json(["code" => -1, "msg" => $validate->getError()]);
		}
		if (!captcha_check($post["code"], "BuyPublic")) {
			return json(["code" => -1, "msg" => "验证码错误"]);
		}
		$result = \app\common\service\AppCardBuy::createRenewalOrder($post);
		if ($result["code"] != 1) {
			return json($result);
		}
		return json(["code" => 1, "msg" => "创建订单成功", "data" => $result["data"]]);
	}
	public function pay($order_id)
	{
		header("content-type:text/html;charset=utf-8");
		$order = \think\Db::name("app_order")->where(["id" => $order_id])->find();
		if (empty($order)) {
			showMessageExit("订单不存在");
		}
		if ($order["pay_status"] == 1) {
			showMessageExit("订单已支付");
		}
		if (time() - $order["create_time"] >= 3600) {
			showMessageExit("订单支付超时");
		}
		$isSystemAuthUnpaid = isSystemAuthUnpaid();
		if ($isSystemAuthUnpaid && \think\Db::name("app_order")->where(["pay_status" => 1])->sum("price") >= \app\common\model\FreeQuota::OrderPayAmountQuota) {
			showMessageExit("当前授权为基础版,所有已付款订单金额上限为" . \app\common\model\FreeQuota::OrderPayAmountQuota . \app\common\model\DefaultConfig::SystemAuthUnpaidSuffixText);
		}
		$orderKey = \app\common\service\AppCardBuy::getOrderKey($order);
		$return_url = getsiteurl();
		if ($order["type"] === \app\common\model\BuyType::CardAppBuyCard || $order["type"] === \app\common\model\BuyType::MemberAppBuyCard || $order["type"] === \app\common\model\BuyType::AuthAppBuyCard) {
			$return_url = getsiteurl() . "/index/buy/CardBuyView/appid/{$order["appid"]}/id/{$order["id"]}/key/{$orderKey}";
		} else {
			if ($order["type"] === \app\common\model\BuyType::AgentRecharge) {
				$return_url = getsiteurl() . "/agent/#/pages/user/user";
			} elseif ($order["type"] === \app\common\model\BuyType::CardAppUserRenewal) {
				$return_url = getsiteurl() . "/index/buy/CardBuyView/appid/{$order["appid"]}";
			}
		}
		if (!empty($this->input["return_url"])) {
			$return_url = $this->input["return_url"];
		}
		$order_name = "购买商品";
		$this->assign("orderName", $order_name);
		$this->assign("order", $order);
		$this->assign("orderKey", $orderKey);
		$this->assign("returnUrl", $return_url);
		$this->assign("currentUrl", $this->request->url(true));
		if ($order["pay_type"] == 1) {
			$this->assign("payType", "wxpay");
			$this->assign("payTypeName", "微信");
		} elseif ($order["pay_type"] == 2) {
			$this->assign("payType", "alipay");
			$this->assign("payTypeName", "支付宝");
		} elseif ($order["pay_type"] == 3) {
			$this->assign("payType", "qqpay");
			$this->assign("payTypeName", "QQ");
		}
		$pay_config = \app\common\server\ConfigServer::get("pay", "config");
		$website = \app\common\server\ConfigServer::get("website");
		$currentHost = parse_url(getsiteurl());
		$systemHost = parse_url($website["url"]);
		if (isset($website["url"]) && $systemHost["host"] != $currentHost["host"]) {
			$this->redirect($website["url"] . $this->request->baseUrl(), $this->request->get());
		}
		if ($order["pay_type"] == 1) {
			if (!$pay_config["wxpay"]["open"]) {
				showMessageExit("微信支付通道已被关闭，请使用其他支付渠道");
			}
			\think\Db::name("app_order")->where(["id" => $order["id"]])->update(["gateway" => $pay_config["wxpay"]["gateway"]]);
			if ($pay_config["wxpay"]["gateway"] == 0) {
				$wxpay_config = \app\common\server\ConfigServer::get("pay", "wxpay");
				if (\think\facade\Request::isMobile()) {
					if ($wxpay_config["mobile_product"] == "H5") {
						$result = (new \app\api\wxpay\H5($wxpay_config))->pay($order["order_no"], $order["price"], $order_name, getsiteurl() . "/index/buy/pay_callback_wxpay/out_trade_no/" . $order["order_no"], $this->request->ip());
						if (is_array($result) && isset($result["h5_url"])) {
							return "<script>window.location.href='" . $result["h5_url"] . "&redirect_url=" . urlencode($return_url) . "';</script>";
						} else {
							showMessageExit("微信 H5 下单失败" . $result);
						}
					} elseif ($wxpay_config["mobile_product"] == "JSAPI") {
						if (strpos($_SERVER["HTTP_USER_AGENT"], "MicroMessenger") !== false) {
							if (isset($this->input["code"])) {
								if (isset($this->input["jsapi"])) {
									$res = json_decode(get_curl("https://api.weixin.qq.com/sns/oauth2/access_token?appid={$wxpay_config["appid"]}&secret={$wxpay_config["app_secret"]}&code={$this->input["code"]}&grant_type=authorization_code"), true);
									if (!empty($res["openid"])) {
										$result = (new \app\api\wxpay\JsApi($wxpay_config))->pay($order["order_no"], $order["price"], $order_name, getsiteurl() . "/index/buy/pay_callback_wxpay/out_trade_no/" . $order["order_no"], $res["openid"]);
										if (is_array($result) && isset($result["appId"])) {
											$this->assign("jsApiParameters", json_encode($result));
											return $this->fetch("./static/pay/html/wxjspay2.html");
										} else {
											showMessageExit("微信 JSAPI 下单失败" . $result);
										}
									} else {
										showMessageExit("微信 JSAPI 下单失败，公众号授权失败");
									}
								} else {
									$parameter_string = "";
									foreach ($this->input as $k => $v) {
										$parameter_string .= "&" . $k . "=" . $v;
									}
									return redirect($website["url"] . "/api/client.order/pay/jsapi/true?" . $parameter_string);
								}
							} else {
								$redirect_uri = urlencode($this->request->baseUrl(true) . "/official_authorization/true");
								$url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$wxpay_config["appid"]}&redirect_uri={$redirect_uri}&response_type=code&scope=snsapi_base&state=state#wechat_redirect";
								return redirect($url);
							}
						} else {
							return $this->fetch("./static/pay/html/wxjspay.html");
						}
					} elseif ($wxpay_config["mobile_product"] == "Native") {
						$result = (new \app\api\wxpay\Native($wxpay_config))->pay($order["order_no"], $order["price"], $order_name, getsiteurl() . "/index/buy/pay_callback_wxpay/out_trade_no/" . $order["order_no"], $this->request->ip());
						if (is_array($result) && isset($result["code_url"])) {
							$qrCode = $result["code_url"];
							$this->assign("qrCode", $qrCode);
							return $this->fetch("./static/pay/html/wxpay.html");
						} else {
							showMessageExit("微信 Native 下单失败" . $result);
						}
					}
				} else {
					if ($wxpay_config["pc_product"] == "Native") {
						$result = (new \app\api\wxpay\Native($wxpay_config))->pay($order["order_no"], $order["price"], $order_name, getsiteurl() . "/index/buy/pay_callback_wxpay/out_trade_no/" . $order["order_no"], $this->request->ip());
						if (is_array($result) && isset($result["code_url"])) {
							$qrCode = $result["code_url"];
							$this->assign("qrCode", $qrCode);
							return $this->fetch("./static/pay/html/wxpay.html");
						} else {
							showMessageExit("微信 Native 下单失败" . $result);
						}
					}
				}
			} elseif ($pay_config["wxpay"]["gateway"] == 1) {
				return \app\api\epay\EpayApi::getPayHtml(\app\common\server\ConfigServer::get("pay", "epay_wxpay"), $order["order_no"], $order["price"], $order_name, "wxpay", getsiteurl() . "/index/buy/pay_callback_epay", $return_url);
			} elseif ($pay_config["wxpay"]["gateway"] == 2) {
				$config = \app\common\server\ConfigServer::get("pay", "ysf_wxpay");
				$ysfconfig = new \app\api\unionpay\ysf\Config();
				$ysfconfig->S("mchId", $config["mchId"]);
				$ysfconfig->S("key", $config["key"]);
				$request = new \app\api\unionpay\ysf\Request($ysfconfig);
				$result = $request->submitOrderInfo(["out_trade_no" => $order["order_no"], "total_fee" => $order["price"] * 100, "mch_create_ip" => \think\facade\Request::ip(), "body" => $order_name], getsiteurl() . "/index/buy/pay_callback_ysf/order_id/{$order["id"]}");
				if (!is_array($result)) {
					showMessageExit("微信下单失败" . $result);
				}
				$qrCode = $result["code_url"];
				$this->assign("qrCode", $qrCode);
				return $this->fetch("./static/pay/html/wxpay.html");
			} elseif ($pay_config["wxpay"]["gateway"] == 3) {
			} elseif ($pay_config["wxpay"]["gateway"] == 4) {
			}
		} elseif ($order["pay_type"] == 2) {
			if (!$pay_config["alipay"]["open"]) {
				showMessageExit("支付宝支付通道已被关闭，请使用其他支付渠道");
			}
			\think\Db::name("app_order")->where(["id" => $order["id"]])->update(["gateway" => $pay_config["alipay"]["gateway"]]);
			if ($pay_config["alipay"]["gateway"] == 0) {
				$alipay_config = \app\common\server\ConfigServer::get("pay", "alipay");
				if (\think\facade\Request::isMobile()) {
					if ($alipay_config["mobile_product"] == "QUICK_WAP_WAY") {
						$result = (new \app\api\alipay\Wap($alipay_config))->pay($order["order_no"], $order["price"], $order_name, getsiteurl() . "/index/buy/pay_callback_alipay", $return_url);
						if (is_array($result)) {
							return $result["body"];
						} else {
							showMessageExit("支付宝 QUICK_WAP_WAY 下单失败" . $result);
						}
					} elseif ($alipay_config["mobile_product"] == "FACE_TO_FACE_PAYMENT") {
						$result = (new \app\api\alipay\FaceToFace($alipay_config))->precreate($order["order_no"], $order["price"], $order_name, getsiteurl() . "/index/buy/pay_callback_alipay");
						if (is_array($result)) {
							$qrCode = $result["qrCode"];
							$this->assign("qrCode", $qrCode);
							return $this->fetch("./static/pay/html/alipay.html");
						} else {
							showMessageExit("支付宝 FACE_TO_FACE_PAYMENT 下单失败" . $result);
						}
					}
				} else {
					if ($alipay_config["pc_product"] == "FAST_INSTANT_TRADE_PAY") {
						$result = (new \app\api\alipay\Page($alipay_config))->pay($order["order_no"], $order["price"], $order_name, getsiteurl() . "/index/buy/pay_callback_alipay", $return_url);
						if (is_array($result)) {
							return $result["body"];
						} else {
							showMessageExit("支付宝 FAST_INSTANT_TRADE_PAY 下单失败" . $result);
						}
					} elseif ($alipay_config["pc_product"] == "FACE_TO_FACE_PAYMENT") {
						$result = (new \app\api\alipay\FaceToFace($alipay_config))->precreate($order["order_no"], $order["price"], $order_name, getsiteurl() . "/index/buy/pay_callback_alipay");
						if (is_array($result)) {
							$qrCode = $result["qrCode"];
							$this->assign("qrCode", $qrCode);
							return $this->fetch("./static/pay/html/alipay.html");
						} else {
							showMessageExit("支付宝 FACE_TO_FACE_PAYMENT 下单失败" . $result);
						}
					}
				}
			} elseif ($pay_config["alipay"]["gateway"] == 1) {
				return \app\api\epay\EpayApi::getPayHtml(\app\common\server\ConfigServer::get("pay", "epay_alipay"), $order["order_no"], $order["price"], $order_name, "alipay", getsiteurl() . "/index/buy/pay_callback_epay", $return_url);
			} elseif ($pay_config["alipay"]["gateway"] == 2) {
				$config = \app\common\server\ConfigServer::get("pay", "ysf_alipay");
				$ysfconfig = new \app\api\unionpay\ysf\Config();
				$ysfconfig->S("mchId", $config["mchId"]);
				$ysfconfig->S("key", $config["key"]);
				$request = new \app\api\unionpay\ysf\Request($ysfconfig);
				$result = $request->submitOrderInfo(["out_trade_no" => $order["order_no"], "total_fee" => $order["price"] * 100, "mch_create_ip" => \think\facade\Request::ip(), "body" => $order_name], getsiteurl() . "/index/buy/pay_callback_ysf/order_id/{$order["id"]}");
				if (!is_array($result)) {
					showMessageExit("支付宝下单失败" . $result);
				}
				$qrCode = $result["code_url"];
				$this->assign("qrCode", $qrCode);
				return $this->fetch("./static/pay/html/alipay.html");
			} elseif ($pay_config["alipay"]["gateway"] == 3) {
				$config = \app\common\server\ConfigServer::get("pay", "jrm_alipay");
				$data = ["mid" => $config["id"], "out_trade_no" => $order["order_no"], "price" => $order["price"], "pay_type" => 2, "notify_url" => getsiteurl() . "/index/buy/pay_callback_jiarenmen", "return_url" => $return_url];
				$data["sign"] = \app\api\jiarenmenpay\Util::getSign($config["key"], $data);
				$url = $config["url"] . "/api/client.order/place_order?";
				foreach ($data as $k => $v) {
					$url .= "&" . $k . "=" . urlencode($v);
				}
				return "<script>window.location.href='{$url}';</script>";
			} elseif ($pay_config["alipay"]["gateway"] == 4) {
				$config = \app\common\server\ConfigServer::get("pay", "hhh_alipay");
				$data = ["out_trade_no" => $order["order_no"], "price" => $order["price"], "pay_type" => 2, "notify_url" => getsiteurl() . "/index/buy/pay_callback_haihaihai", "return_url" => $return_url];
				$data["sign"] = \app\api\jiarenmenpay\Util::getSign($config["key"], $data);
				$result = json_decode(get_curl($config["url"] . "/api/api/createOrder", $data), true);
				if (isset($result["code"])) {
					if ($result["code"] == 1) {
						$qrCode = $result["data"]["code_url"];
						$this->assign("qrCode", $qrCode);
						$this->assign("payTypeName", "支付宝");
						$this->assign("out_trade_no", $order["order_no"]);
						$this->assign("timeout_time", $result["data"]["timeout_time"] - time());
						$this->assign("price", $result["data"]["price"]);
						$this->assign("original_price", $result["data"]["original_price"]);
						return $this->fetch("./static/pay/html/codepay.html");
					} else {
						showMessageExit("支付宝下单失败" . $result["message"]);
					}
				} else {
					showMessageExit("支付宝下单失败" . $result);
				}
			}
		} elseif ($order["pay_type"] == 3) {
			if (!$pay_config["qqpay"]["open"]) {
				showMessageExit("QQ支付通道已被关闭，请使用其他支付渠道");
			}
			\think\Db::name("app_order")->where(["id" => $order["id"]])->update(["gateway" => $pay_config["qqpay"]["gateway"]]);
			if ($pay_config["qqpay"]["gateway"] == 0) {
				$qqpay_config = \app\common\server\ConfigServer::get("pay", "qqpay");
				$result = \app\api\qqpay\Pay::pay($qqpay_config, $order["order_no"], $order["price"], $order_name, getsiteurl() . "/index/buy/pay_callback_qqpay");
				if (is_array($result)) {
					$qrCode = $result["code_url"];
					$this->assign("qrCode", $qrCode);
					return $this->fetch("./static/pay/html/qqpay.html");
				} else {
					showMessageExit("QQ下单失败" . $result);
				}
				if (\think\facade\Request::isMobile()) {
				}
			} elseif ($pay_config["qqpay"]["gateway"] == 1) {
				return \app\api\epay\EpayApi::getPayHtml(\app\common\server\ConfigServer::get("pay", "epay_qqpay"), $order["order_no"], $order["price"], $order_name, "qqpay", getsiteurl() . "/index/buy/pay_callback_epay", $return_url);
			}
		}
	}
	public function get_order_info()
	{
		$get = $this->request->get();
		$validate = \think\Validate::make(["order_id" => "require", "order_key" => "require"], ["order_id.require" => "订单ID 不能为空", "order_key.require" => "order_key 不能为空"]);
		if (!$validate->check($get)) {
			return json(["code" => -1, "msg" => $validate->getError()]);
		}
		$result = \app\common\service\AppCardBuy::getOrderInfo($get);
		if ($result["code"] != 1) {
			return json($result);
		}
		return json(["code" => 1, "msg" => "查询成功", "data" => $result["data"]]);
	}
	public function QueryCardBuyOrder()
	{
		$post = $this->request->post();
		$validate = \think\Validate::make(["type" => "require|in:1,2", "appid" => "require", "value" => "require", "code" => "require"], ["type.require" => "查询方式 不能为空", "appid.require" => "appid 不能为空", "value.require" => "查询内容 不能为空", "type.in" => "查询方式 错误", "code.in" => "图形验证码 不能为空"]);
		if (!$validate->check($post)) {
			return json(["code" => -1, "msg" => $validate->getError()]);
		}
		if (!captcha_check($post["code"], "BuyPublic")) {
			return json(["code" => -1, "msg" => "验证码错误"]);
		}
		$result = \app\common\service\AppCardBuy::queryCardBuyOrder($post);
		if ($result["code"] != 1) {
			return json($result);
		}
		return json(["code" => 1, "msg" => "查询成功", "data" => $result["data"]]);
	}
	public function QueryCardBuyOrderDeliveryData()
	{
		$post = $this->request->post();
		$validate = \think\Validate::make(["order_no" => "require", "password" => "require"], ["order_no.require" => "订单编号 不能为空", "password.require" => "查询密码 不能为空"]);
		if (!$validate->check($post)) {
			return json(["code" => -1, "msg" => $validate->getError()]);
		}
		$result = \app\common\service\AppCardBuy::queryCardBuyOrderDeliveryData($post);
		if ($result["code"] != 1) {
			return json($result);
		}
		return json(["code" => 1, "msg" => "查询成功", "data" => $result["data"]]);
	}
	public function pay_callback_wxpay()
	{
		$out_trade_no = input("out_trade_no");
		try {
			$headers = \think\facade\Request::header();
			$inWechatpaySignature = $headers["wechatpay-signature"];
			$inWechatpayTimestamp = $headers["wechatpay-timestamp"];
			$inWechatpaySerial = $headers["wechatpay-serial"];
			$inWechatpayNonce = $headers["wechatpay-nonce"];
			$inBody = file_get_contents("php://input");
			$config = \app\common\server\ConfigServer::get("pay", "wxpay");
			$apiv3Key = $config["apiv3key"];
			$platformPublicKeyInstance = \WeChatPay\Crypto\Rsa::from("file://" . get_cert_path("system", "wechat.platformCertificate.pem", $config["platformCertificate"]), \WeChatPay\Crypto\Rsa::KEY_TYPE_PUBLIC);
			$timeOffsetStatus = abs(\WeChatPay\Formatter::timestamp() - \intval($inWechatpayTimestamp)) <= 300;
			$verifiedStatus = \WeChatPay\Crypto\Rsa::verify(\WeChatPay\Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody), $inWechatpaySignature, $platformPublicKeyInstance);
			if ($timeOffsetStatus && $verifiedStatus) {
				$inBodyArray = (array) json_decode($inBody, true);
				list("resource" => list("ciphertext" => $ciphertext, "nonce" => $nonce, "associated_data" => $aad)) = $inBodyArray;
				$inBodyResource = \WeChatPay\Crypto\AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad);
				$inBodyResourceArray = (array) json_decode($inBodyResource, true);
				$data = $inBodyResourceArray;
				$order = \think\Db::name("app_order")->where("order_no", $data["out_trade_no"])->find();
				$result = self::payment_callback($order, $data, 0);
				return json($result);
			} else {
				return json(["code" => "FAIL", "message" => "失败"]);
			}
		} catch (\Exception $e) {
			return json(["code" => "FAIL", "message" => "失败"]);
		}
	}
	public function pay_callback_alipay()
	{
		try {
			$order = \think\Db::name("app_order")->where("order_no", $_POST["out_trade_no"])->find();
			if (empty($order)) {
				return "fail";
			}
			$result = (new \app\api\alipay\VerifyNotify(\app\common\server\ConfigServer::get("pay", "alipay")))->verifyNotify($_POST);
			if ($result && $_POST["trade_status"] == "TRADE_SUCCESS") {
				$return = self::payment_callback($order, $_POST, 0);
				if ($return["code"] == "SUCCESS") {
					return "success";
				} else {
					return "fail";
				}
			} else {
				return "fail";
			}
		} catch (\Exception $e) {
			return "fail";
		}
	}
	public function pay_callback_qqpay()
	{
		$wxxml = file_get_contents("php://input");
		$jsonxml = json_encode(simplexml_load_string($wxxml, "SimpleXMLElement", LIBXML_NOCDATA));
		$params = json_decode($jsonxml, true);
		if (!$params) {
			return "<xml><return_code>FAIL</return_code><return_msg>参数错误</return_msg></xml>";
		}
		if ($params["sign"] == \app\api\qqpay\Pay::getSign(\app\common\server\ConfigServer::get("pay", "qqpay"), $params)) {
			$order = \think\Db::name("app_order")->where("order_no", $params["out_trade_no"])->find();
			if (empty($order)) {
				return "<xml><return_code>FAIL</return_code><return_msg>订单不存在</return_msg></xml>";
			}
			$return = self::payment_callback($order, $params, 0);
			if ($return["code"] == "SUCCESS") {
				return "<xml><return_code>SUCCESS</return_code></xml>";
			} else {
				return "<xml><return_code>FAIL</return_code></xml>";
			}
		} else {
			return "<xml><return_code>FAIL</return_code><return_msg>签名错误</return_msg></xml>";
		}
	}
	public function pay_callback_epay()
	{
		try {
			$params = $_GET;
			if ($params["type"] == "alipay") {
				$config = \app\common\server\ConfigServer::get("pay", "epay_alipay");
			} elseif ($params["type"] == "wxpay") {
				$config = \app\common\server\ConfigServer::get("pay", "epay_wxpay");
			} elseif ($params["type"] == "qqpay") {
				$config = \app\common\server\ConfigServer::get("pay", "epay_qqpay");
			}
			if (\app\api\epay\EpayApi::verifySign($config)) {
				$order = \think\Db::name("app_order")->where("order_no", $params["out_trade_no"])->find();
				if (empty($order)) {
					return "fail";
				}
				$return = self::payment_callback($order, $params, 1);
				if ($return["code"] == "SUCCESS") {
					return "success";
				} else {
					return "fail";
				}
			} else {
				return "fail";
			}
		} catch (\Exception $e) {
			return "fail";
		}
	}
	public function pay_callback_ysf()
	{
		try {
			$order_id = input("order_id");
			$order = \think\Db::name("app_order")->where("id", $order_id)->find();
			if ($order["pay_type"] == 1) {
				$config = \app\common\server\ConfigServer::get("pay", "ysf_wxpay");
			} else {
				$config = \app\common\server\ConfigServer::get("pay", "ysf_alipay");
			}
			$ysfconfig = new \app\api\unionpay\ysf\Config();
			$ysfconfig->S("mchId", $config["mchId"]);
			$ysfconfig->S("key", $config["key"]);
			$request = new \app\api\unionpay\ysf\Request($ysfconfig);
			$result = $request->callback();
			if ($result === false) {
				return "fail";
			} else {
				$return = self::payment_callback($order, $result, 2);
				if ($return["code"] == "SUCCESS") {
					return "success";
				} else {
					return "fail";
				}
			}
		} catch (\Exception $e) {
			return "fail";
		}
	}
	public function pay_callback_jiarenmen()
	{
		try {
			$params = $_POST;
			if ($params["pay_type"] == "2") {
				$config = \app\common\server\ConfigServer::get("pay", "jrm_alipay");
			} elseif ($params["pay_type"] == "1") {
				$config = \app\common\server\ConfigServer::get("pay", "jrm_wxpay");
			} elseif ($params["pay_type"] == "3") {
				$config = \app\common\server\ConfigServer::get("pay", "jrm_qqpay");
			}
			$sign = \app\api\jiarenmenpay\Util::getSign($config["key"], $params);
			if ($sign == $_POST["sign"]) {
				$order = \think\Db::name("app_order")->where("order_no", $params["out_trade_no"])->find();
				if (empty($order)) {
					return "fail";
				}
				$return = self::payment_callback($order, $params, 3);
				if ($return["code"] == "SUCCESS") {
					return "success";
				} else {
					return "fail";
				}
			} else {
				return "fail";
			}
		} catch (\Exception $e) {
			return "fail";
		}
	}
	public function pay_callback_haihaihai()
	{
		try {
			$params = $_POST;
			if ($params["pay_type"] == "2") {
				$config = \app\common\server\ConfigServer::get("pay", "hhh_alipay");
			} elseif ($params["pay_type"] == "1") {
				$config = \app\common\server\ConfigServer::get("pay", "hhh_wxpay");
			} elseif ($params["pay_type"] == "3") {
				$config = \app\common\server\ConfigServer::get("pay", "hhh_qqpay");
			}
			$sign = \app\api\jiarenmenpay\Util::getSign($config["key"], $params);
			if ($sign == $_POST["sign"]) {
				$order = \think\Db::name("app_order")->where("order_no", $params["out_trade_no"])->find();
				if (empty($order)) {
					return "fail";
				}
				$return = self::payment_callback($order, $params, 4);
				if ($return["code"] == "SUCCESS") {
					return "success";
				} else {
					return "fail";
				}
			} else {
				return "fail";
			}
		} catch (\Exception $e) {
			return "fail";
		}
	}
	public static function payment_callback($order, $data, $gateway)
	{
		if (!is_array($order)) {
			$order = \think\Db::name("app_order")->where("id", $order)->find();
		}
		if (!$order) {
			return ["code" => "FAIL", "msg" => "订单不存在"];
		}
		if ($order["pay_status"] != 0) {
			return ["code" => "SUCCESS", "msg" => "订单已支付"];
		}
		$update = ["pay_status" => 1, "gateway" => $gateway, "payment_time" => time()];
		\think\Db::startTrans();
		try {
			if ($gateway == 0) {
				if ($order["pay_type"] == 1) {
					$update["supplier_no"] = $data["transaction_id"];
				} elseif ($order["pay_type"] == 2) {
					$update["supplier_no"] = $data["trade_no"];
				} elseif ($order["pay_type"] == 3) {
					$update["supplier_no"] = $data["transaction_id"];
				}
			} elseif ($gateway == 1) {
				$update["supplier_no"] = $data["trade_no"];
			} elseif ($gateway == 2) {
				$update["supplier_no"] = $data["out_transaction_id"];
			} elseif ($gateway == 3) {
				$update["supplier_no"] = $data["order_no"];
			} elseif ($gateway == 4) {
				$update["supplier_no"] = $data["order_no"];
			}
			$date = date("Y-m-d H:i:s");
			$add_card_extra_params = [];
			if ($order["type"] === \app\common\model\BuyType::CardAppBuyCard || $order["type"] === \app\common\model\BuyType::MemberAppBuyCard || $order["type"] === \app\common\model\BuyType::AuthAppBuyCard) {
				$app = \think\Db::name("app")->where(["id" => $order["appid"]])->find();
				$buy_config = json_decode($app["buy_config"], true);
				$type = $order["goods_type"];
				$defaultMinLength = \app\common\model\DefaultConfig::AppDefaultAddCardMinLength;
				$head = $buy_config["common_buy_card"]["card_structure_head"] ?? "";
				$foot = $buy_config["common_buy_card"]["card_structure_foot"] ?? "";
				$card_structure_body = $buy_config["common_buy_card"]["card_structure_body"] ?? 0;
				$card_structure_body_length = $buy_config["common_buy_card"]["card_structure_body_length"] ?? 0;
				$card_structure_body_transform = $buy_config["common_buy_card"]["card_structure_body_transform"] ?? 0;
				if (isset($buy_config["common_buy_card"]["add_card_structure_head_config"][$type]) && $buy_config["common_buy_card"]["add_card_structure_head_config"][$type] !== "") {
					$head = $buy_config["common_buy_card"]["add_card_structure_head_config"][$type];
				}
				if (isset($buy_config["common_buy_card"]["add_card_structure_body_config"][$type]) && $buy_config["common_buy_card"]["add_card_structure_body_config"][$type] !== "") {
					$card_structure_body = $buy_config["common_buy_card"]["add_card_structure_body_config"][$type];
				}
				if (isset($buy_config["common_buy_card"]["add_card_structure_body_length_config"][$type]) && $buy_config["common_buy_card"]["add_card_structure_body_length_config"][$type] !== "") {
					$card_structure_body_length = $buy_config["common_buy_card"]["add_card_structure_body_length_config"][$type];
				}
				if (isset($buy_config["common_buy_card"]["add_card_structure_body_transform_config"][$type]) && $buy_config["common_buy_card"]["add_card_structure_body_transform_config"][$type] !== "") {
					$card_structure_body_transform = $buy_config["common_buy_card"]["add_card_structure_body_transform_config"][$type];
				}
				if (isset($buy_config["common_buy_card"]["add_card_structure_foot_config"][$type]) && $buy_config["common_buy_card"]["add_card_structure_foot_config"][$type] !== "") {
					$foot = $buy_config["common_buy_card"]["add_card_structure_foot_config"][$type];
				}
				if ($card_structure_body_length < $defaultMinLength) {
					$card_structure_body_length = $defaultMinLength;
				}
				$add_card_extra_params = ["head" => $head, "foot" => $foot, "body" => $card_structure_body, "card_length" => $card_structure_body_length, "transform" => $card_structure_body_transform];
			}
			if ($order["type"] === \app\common\model\BuyType::CardAppBuyCard) {
				$result = \app\system\service\CardAppService::add_card(array_merge(["appid" => $order["appid"], "num" => $order["goods_num"], "time_type" => $order["goods_type"], "time_value" => $order["goods_value"], "batch_remarks" => "在线支付购卡系统自动生成"], $add_card_extra_params));
				$update["delivery_data"] = json_encode($result["data"], JSON_UNESCAPED_UNICODE);
			} elseif ($order["type"] === \app\common\model\BuyType::MemberAppBuyCard) {
				$type = \app\common\model\CardType::Time[0];
				if ($order["goods_type"] == "register_code") {
					$type = \app\common\model\CardType::RegisterCode[0];
				} elseif ($order["goods_type"] == "point") {
					$type = \app\common\model\CardType::Point[0];
				}
				$result = \app\system\service\MemberAppService::add_card(array_merge(["appid" => $order["appid"], "num" => $order["goods_num"], "type" => $type, "value" => $order["goods_value"], "time_type" => $order["goods_type"] == "point" ? 0 : $order["goods_type"], "batch_remarks" => "在线支付购卡系统自动生成"], $add_card_extra_params));
				$update["delivery_data"] = json_encode($result["data"], JSON_UNESCAPED_UNICODE);
			} elseif ($order["type"] === \app\common\model\BuyType::AuthAppBuyCard) {
				$type = \app\common\model\CardType::Time[0];
				if ($order["goods_type"] == "register_code") {
					$type = \app\common\model\CardType::RegisterCode[0];
				}
				$result = \app\system\service\AuthAppService::add_card(array_merge(["appid" => $order["appid"], "num" => $order["goods_num"], "type" => $type, "value" => $order["goods_value"], "time_type" => $order["goods_type"] == "point" ? 0 : $order["goods_type"], "batch_remarks" => "在线支付购卡系统自动生成"], $add_card_extra_params));
				$update["delivery_data"] = json_encode($result["data"], JSON_UNESCAPED_UNICODE);
			} elseif ($order["type"] === \app\common\model\BuyType::AgentRecharge) {
				$agent = \think\Db::name("app_agent")->where("id", $order["user"])->find();
				\app\common\AppAgent::money($agent, $order["goods_value"], 0, "在线充值,订单:" . $order["order_no"]);
			} elseif ($order["type"] === \app\common\model\BuyType::CardAppUserRenewal) {
				$user = \think\Db::name("app_card_user")->where(["id" => $order["user"]])->find();
				$field = "endtime";
				if ($user[$field] > time()) {
					$date = date("Y-m-d H:i:s", $user[$field]);
				}
				if ($order["goods_type"] == "point") {
					$field = $order["goods_type"];
					$number = $order["goods_value"];
				} else {
					$number = \app\common\helper\Time::computing_time($order["goods_type"], $order["goods_value"], strtotime($date));
				}
				\app\api\common\card\Finance::set($user, "endtime", $number, 0, "在线交易订单开通,订单号:{$order["order_no"]}", \app\common\model\CardAppModel::UserCardEndTimeLogSourceCardRenewalOrder);
			} elseif ($order["type"] === \app\common\model\BuyType::MemberAppUserRenewal) {
				$user = \think\Db::name("app_member_user")->where(["id" => $order["user"]])->find();
				$field = "viptime";
				if ($user[$field] > time()) {
					$date = date("Y-m-d H:i:s", $user[$field]);
				}
				if ($order["goods_type"] == "point") {
					$field = $order["goods_type"];
					$number = $order["goods_value"];
				} else {
					$number = \app\common\helper\Time::computing_time($order["goods_type"], $order["goods_value"], strtotime($date));
				}
				\app\api\common\member\Finance::set($user, $field, $number, 0, "在线交易订单开通,订单号:{$order["order_no"]}", \app\common\model\MemberAppModel::UserVipTimeLogSourceRenewalOrder);
			} elseif ($order["type"] === \app\common\model\BuyType::AuthAppUserRenewal) {
				$user = \think\Db::name("app_auth_user")->where(["id" => $order["user"]])->find();
				if (!empty($user)) {
					$field = "endtime";
					if ($user[$field] > time()) {
						$date = date("Y-m-d H:i:s", $user[$field]);
					}
					if ($order["goods_type"] == "point") {
						$field = $order["goods_type"];
						$number = $order["goods_value"];
					} else {
						$number = \app\common\helper\Time::computing_time($order["goods_type"], $order["goods_value"], strtotime($date));
					}
					\app\api\common\auth\Finance::set($user, $field, $number, 0, "在线交易订单开通,订单号:{$order["order_no"]}", \app\common\model\AuthAppModel::UserEndTimeLogSourceRenewalOrder);
				} else {
					$endtime = \app\common\helper\Time::computing_time($order["goods_type"], $order["goods_value"], strtotime($date));
					$uid = \think\Db::name("app_auth_user")->insertGetId(["appid" => $order["appid"], "auth" => $order["user"], "addtime" => time(), "endtime" => $endtime, "is_forever_auth" => \intval($endtime === \app\common\model\DefaultConfig::PerpetualTimeValue)]);
					\think\Db::name("app_auth_user_change_log")->insert(["appid" => $order["appid"], "uid" => $uid, "new" => $order["user"], "source" => \app\common\model\AuthAppModel::UserChangeBindingLogSourceInit, "time" => time(), "remarks" => "在线支付开通授权"]);
					\app\common\server\StatisticsData::increases($order["appid"], \app\common\model\AppData::AuthAppNewUserActivation, 1);
				}
			}
			if ($order["type"] === \app\common\model\BuyType::MemberAppBuyCard || $order["type"] === \app\common\model\BuyType::CardAppBuyCard) {
				$app = \think\Db::name("app")->where(["id" => $order["appid"]])->find();
				$buy_config = json_decode($app["buy_config"], true);
				if (!empty($buy_config["common_buy_card"]["card_buy_deliver_notice"])) {
					list($channel_type, $config) = get_sms_config();
					$delivery_data = json_decode($update["delivery_data"], true);
					if (count($delivery_data["list"]) > 1) {
						$card_text = "";
						foreach ($delivery_data["list"] as $card_index => $card_item) {
							$card_text .= ",第" . ($card_index + 1) . "个卡密:" . $card_item;
						}
						$card_text = ltrim($card_text, ",");
					} else {
						$card_text = $delivery_data["list"][0];
					}
					\app\common\server\Sms::card_buy_deliver($channel_type, $config, $order["user"], $order["order_no"], $card_text);
				}
			}
			\think\Db::name("app_order")->where(["id" => $order["id"]])->update($update);
			\think\Db::commit();
			return ["code" => "SUCCESS", "msg" => "成功"];
		} catch (\think\Exception $e) {
			\think\Db::rollback();
			return ["code" => "FAIL", "msg" => $e->getMessage()];
		}
	}
	public static function MakeSign($params, $key)
	{
		ksort($params);
		$string = self::ToUrlParams($params);
		$string = $string . "&key=" . $key;
		$string = md5($string);
		$result = strtoupper($string);
		return $result;
	}
	public static function ToUrlParams($params)
	{
		$string = "";
		if (!empty($params)) {
			$array = [];
			foreach ($params as $key => $value) {
				if ($key != "sign") {
					$array[] = $key . "=" . $value;
				}
			}
			$string = implode("&", $array);
		}
		return $string;
	}
}